<?php
namespace common\models\user;

use api\modules\v1\models\circle\CircleComment;
use api\modules\v1\models\userReceipt\Receipt;
use common\models\circle\CircleCommentAtRelation;
use common\models\circle\CircleUserRelation;
use common\models\Common;
use common\models\friend\Friend;
use common\models\friend\FriendApply;
use common\models\Functions;
use common\models\group\GroupApply;
use common\models\group\GroupUser;
use common\models\im\Im;
use common\models\im\ImQrcode;
use common\models\shop\GoodsOrder;
use common\models\Status;
use common\models\userFund\UserMoney;
use common\models\userReceipt\ReceiptBank;
use Yii;
use yii\base\Exception;

class User extends Common
{

    public static function tableName()
    {
        return '{{%user}}';
    }


    public function getBank()
    {
        return $this->hasOne(ReceiptBank::className(), ['user_id' => 'id']);
    }


    public function getMoney()
    {
        return $this->hasOne(UserMoney::className(), ['user_id' => 'id']);
    }

    public function getKyc()
    {
        return $this->hasOne(UserReal::className(), ['user_id' => 'id']);
    }

    // 是否是好友
    public function getIsFriend()
    {
        return $this->hasOne(Friend::className(), ['friend_id' => 'id']);
    }

    // 是否是群成员
    public function getIsGroupUser()
    {
        return $this->hasOne(GroupUser::className(), ['user_id' => 'id']);
    }

    // 是否邀请过
    public function getIsGroupApply()
    {
        return $this->hasOne(GroupApply::className(), ['user_id' => 'id']);
    }


    // 关联好友申请
    public function getUserApplyCount() {
        return $this->hasOne(FriendApply::className(), ['friend_id' => 'id'])->onCondition(['status' => Status::COMMON_CHECKING_WAITING]);
    }

    // 关联群申请
    public function getGroupApplyInviteCount() {
        return $this->hasOne(GroupApply::className(), ['user_id' => 'id'])->onCondition([
            'status' => Status::COMMON_CHECKING_WAITING,
            'be_invited_status' => Status::COMMON_CHECKING_SUCCESS,
        ]);
    }

    // 关联被邀请
    public function getGroupBeApplyInviteCount() {
        return $this->hasOne(GroupApply::className(), ['user_id' => 'id'])->onCondition(['be_invited_status' => Status::COMMON_CHECKING_WAITING]);
    }

    // 圈子被点赞数量
    public function getCircleLikeCount() {
        return $this->hasOne(CircleUserRelation::className(), ['topic_user_id' => 'id'])->onCondition([
            'type' => Status::CIRCLE_USER_RELATION_TYPE_LIKE,
            'is_read' => Status::COMMON_RADIO_NO,
        ]);
    }

    // 圈子被收藏数量
    public function getCircleCollectCount() {
        return $this->hasOne(CircleUserRelation::className(), ['topic_user_id' => 'id'])->onCondition([
            'type' => Status::CIRCLE_USER_RELATION_TYPE_COLLECT,
            'is_read' => Status::COMMON_RADIO_NO,
        ]);
    }

    // 新增关注的数量
    public function getAttentionCount() {
        return $this->hasOne(UserAttention::className(), ['topic_id' => 'id'])->onCondition([
            'is_read' => Status::COMMON_RADIO_NO,
        ]);
    }

    // 评论数量
    public function getCommentCount() {
        return $this->hasOne(CircleComment::className(), ['topic_user_id' => 'id'])->onCondition([
            'is_read' => Status::COMMON_RADIO_NO,
        ]);
    }

    // 评论@数量
    public function getCommentAtCount() {
        return $this->hasOne(CircleCommentAtRelation::className(), ['topic_user_id' => 'id'])->onCondition([
            'is_read' => Status::COMMON_RADIO_NO,
        ]);
    }

    // 是否打过招呼
    public function getIsGreet()
    {
        return $this->hasOne(UserGreet::className(), ['greet_user_id' => 'id']);
    }

    // 打招呼数量
    public function getGreetCount() {
        return $this->hasOne(UserGreet::className(), ['greet_user_id' => 'id'])->onCondition([
            'is_read' => Status::COMMON_RADIO_NO,
        ]);
    }

    protected function _createNickname()
    {
        $pre = Yii::$app->params['PLATFORM_NAME'] ?: "聊天";
        do {
            $nickName = $pre . rand(100000, 999999);
            $exist = static::getOneByWhere(['nick_name' => $nickName]);
        } while ($exist > 0);
        return $nickName;
    }

    /**
     * 生成邀请码
     * @return int
     */
    protected function _createInviteCode()
    {
        do {
            $code = Functions::randLetterNumber(8);
            $exist = static::getOneByWhere(['invite_code' => $code]);
        } while ($exist > 0);

        return $code;
    }


    // 创建腾讯code
    public function createTxCode()
    {
        do {
            $txCode = Functions::generateCode(15);
            $exist = static::getOneByWhere(['tx_code' => $txCode]);
        } while ($exist > 0);
        return $txCode;
    }

    // 创建code
    public function createCode($length = 10)
    {
        do {
            $code = Functions::generateCode($length);
            $exist = static::getOneByWhere(['user_code' => $code]);
        } while ($exist > 0);
        return $code;
    }

    /**
     * 创建IM用户信息
     * @return mixed
     * @throws Exception
     */
    public function createImUser($user = []) {

        // 创建im账号
        //1.二维码 腾讯code 昵称
        $txCode = $this->createTxCode();
        $imUserFace = static::getAvatar($user['user_face']);

        $qrCode = (new ImQrcode())->userQrCode($user['id'], $txCode, $imUserFace);

        $imUser['tx_code'] = $txCode;
        $imUser['user_code'] = $this->createCode(8);
        $imUser['qr_code'] = $qrCode;
        $imUser['is_auto_enter_group'] = Status::COMMON_RADIO_YES;
        $imUser['signature'] = '';


        $resIm = (new Im()) -> addUser($imUser['tx_code'], $user['nick_name'], $imUserFace);
        if (!$resIm) {
            throw new Exception('聊天账号创建失败');
        }

        $resImUser = static::updateData($imUser,['id' => $user['id']]);
        if (!$resImUser) {
            throw new Exception('聊天账号创建失败');
        }

        $imUser['id'] = $user['id'];

        // 更新用户信息
        $updateImUser['Tag_Profile_IM_Nick'] = $user['nick_name'];
        $updateImUser['Tag_Profile_IM_Image'] = static::getAvatar($user['user_face']);
        $updateImUser['Tag_Profile_IM_SelfSignature'] = '暂无个性签名';
        $updateImUser['Tag_Profile_IM_AllowType'] = 'AllowType_Type_NeedConfirm'; //需要经过自己确认才能添加自己为好友
        $updateImUser['Tag_Profile_Custom_Qrcode'] = static::getImages($imUser['qr_code']);
        $updateImUser['Tag_Profile_Custom_code'] = (string) $imUser['user_code'];
//        $updateImUser['Tag_Profile_Custom_phone'] = $user['phone'];
        $resIm = (new Im()) -> updateUser($imUser['tx_code'], $updateImUser);
        if (!$resIm) {
            throw new Exception('更新用户信息失败');
        }
        return $imUser;
    }

    public function checkInfo($user = [])
    {
        # 检查支付密码
        if (!$user['pay_password']) {
            throw new Exception('请先设置支付密码',1002);
        }

        if ($user['is_kyc'] == Status::COMMON_RADIO_NO) {
            throw new Exception('请先进行实名认证',1003);
        }

        if ($user['money_switch'] == Status::COMMON_RADIO_NO) {
            throw new Exception('钱包锁已被关闭',1004);
        }

//        # 检查银行卡和支付密码
//        $receipt = (new Receipt())->getReceiptByUserId($userId);
//        if (empty($receipt['bank'])) {
//            throw new Exception('请绑定银行卡，如果无法绑定，请升级APP');
//        }
    }

    // 添加客服为好友
    public function addServerUserFriend($userId = 0) {
        $config = static::getCommonByKey(['server_user_id']);
        $serverUserInfo = User::getOneByWhere(['tx_code' => $config['server_user_id']]);
        if (empty($serverUserInfo)) {
            return true;
        }


        // 查询客服的好友数量
        $serverFriendWhere = $serverFriendAndWhere = [];
        $serverFriendAndWhere[] = [
            'or',
            ['=','user_id',$serverUserInfo['id']],
            ['=','friend_id',$serverUserInfo['id']],
        ];
        $serverFriendCount = Friend::getCountByAndWhere($serverFriendWhere,$serverFriendAndWhere);
        if ($serverFriendCount >= 3000) {
            throw new Exception('当前客服账号好友已满，请联系管理员更换客服账号！');
        }

        // 每个用户只需添加一个客服好友
        $userServerFriendInfo = Friend::getOneByWhere([
            'friend_id' => $userId,
            'user_id' => $serverUserInfo['id'],
        ]);

        if (empty($userServerFriendInfo)) {
            // 添加好友
            (new Friend())->addFriend($serverUserInfo['id'],$userId);
        }
    }

    // 检查是否可以发红包
    public function checkRedPacketInfo($user = [])
    {
        # 检查支付密码
        if (!$user['pay_password']) {
            throw new Exception('请先设置支付密码',1002);
        }

        if ($user['money_switch'] == Status::COMMON_RADIO_NO) {
            throw new Exception('钱包锁已被关闭',1004);
        }

        //判断是否需要实名
        $config = static::getCommonByKey(['switch_red_packet_kyc','switch_check_trade']);
        if ($config['switch_red_packet_kyc'] == Status::COMMON_RADIO_YES && $user['is_kyc'] == Status::COMMON_RADIO_NO) {
            throw new Exception('请先去实名认证！');
        }

        //判断当前用户状态
        UserUnusualLog::checkUserUnusual($user['id'],Status::USER_UNUSUAL_TYPE_RED_PACKET);

        # 需要产生实际交易
        if ($config['switch_check_trade'] == Status::COMMON_RADIO_YES) {
            $orderWhere['user_id'] = $user['id'];
            $orderWhere['status'] = [
                Status::USER_GOODS_ORDER_STATUS_WAITING_SEND,
                Status::USER_GOODS_ORDER_STATUS_WAITING_RECEIVE,
                Status::USER_GOODS_ORDER_STATUS_DONE,
            ];
            $orderCount = GoodsOrder::getCountByWhere($orderWhere);
            if ($orderCount <= 0) {
                throw new Exception('请先购买商城商品，才能使用红包功能', 1005);
            }
        }
    }

    // 检查是否可领取发红包
    public function checkReceiveRedPacketInfo($user = [])
    {
        # 检查支付密码
        if (!$user['pay_password']) {
            throw new Exception('请先设置支付密码',1002);
        }

//        if ($user['money_switch'] == Status::COMMON_RADIO_NO) {
//            throw new Exception('钱包锁已被关闭',1004);
//        }

        //判断是否需要实名
        $config = static::getCommonByKey(['switch_red_packet_kyc','switch_check_trade']);
        if ($config['switch_red_packet_kyc'] == Status::COMMON_RADIO_YES && $user['is_kyc'] == Status::COMMON_RADIO_NO) {
            throw new Exception('请先去实名认证！');
        }

        //判断当前用户状态
        UserUnusualLog::checkUserUnusual($user['id'],Status::USER_UNUSUAL_TYPE_RED_PACKET);

        if ($config['switch_check_trade'] == Status::COMMON_RADIO_YES) {
            # 需要产生实际交易
            $orderWhere['user_id'] = $user['id'];
            $orderWhere['status'] = [
                Status::USER_GOODS_ORDER_STATUS_WAITING_SEND,
                Status::USER_GOODS_ORDER_STATUS_WAITING_RECEIVE,
                Status::USER_GOODS_ORDER_STATUS_DONE,
            ];
            $orderCount = GoodsOrder::getCountByWhere($orderWhere);
            if ($orderCount <= 0) {
                throw new Exception('请先购买商城商品，才能使用红包功能',1005);
            }
        }

    }

    public function getRegisterNum($date = '')
    {

        if (empty($date)) {
            return 0;
        }
        # 查询条件
        $currDateStart = $date . ' 00:00:00';
        $currDateEnd = $date . ' 23:59:59';
        $andWhere = ['between', 'register_time', $currDateStart, $currDateEnd];

        if ($date == date("Y-m-d")) {
            $registerNum = (int)static::getCountByAndWhere([], $andWhere);
            return $registerNum;
        }

        $cache = \Yii::$app->cache;
        $prefix = "REGISTER_NUM_";
        $key = $prefix . $date;
        $registerNum = $cache->get($key);
        if ($registerNum === false) {
            $registerNum = (int)static::getCountByAndWhere([], $andWhere);
            $cache->set($key, $registerNum);
        }

        return $registerNum;
    }

    // 通过名字获取ID  模糊匹配
    public static function searchByName($loginName = '')
    {
        $where = [];
        $andWhere[] = ['like', "login_name", $loginName];

        $list = static::getByAndWhere($where, $andWhere, ['id']);

        return array_column($list, "id");
    }

    // 重新定位
    public function setPosition($user = []) {

        if (empty($user['longitude']) || empty($user['latitude'])) {
            # 位置
            list($longitude,$latitude) = $this->getPosition($user['phone']);
            if ($longitude && $latitude) {
                $data['longitude'] = $longitude;
                $data['latitude'] = $latitude;

                static::updateData($data,['id' => $user['id']]);
            }
        }
    }
}
